;********************************************************************************************************
;                                               uC/OS-II
;                                        The Real-Time Kernel
;
;                            (c) Copyright 1992-2010, Micrium, Inc., Weston, FL
;                    All rights reserved.  Protected by international copyright laws.
;
;                                           Renesas RX630
;
; File    : OS_CPU_A.SRC
; Version : V2.92.07
;********************************************************************************************************

                                         ; Include OS_CTX_SAVE and OS_CTX_RESTORE macros
    .INCLUDE    os_cpu_a.inc


;********************************************************************************************************
;                                           PUBLIC FUNCTIONS
;********************************************************************************************************

    .GLB     _OSStartHighRdy             ; Public functions
    .GLB     _OSCtxSw
    .GLB     _OSIntCtxSw

    .GLB     _OSRunning                  ; External function references
    .GLB     _OSPrioCur                  ; Declared as INT8U                  ,  8-bit long
    .GLB     _OSPrioHighRdy              ; Declared as INT8U                  ,  8-bit long
    .GLB     _OSTCBCur
    .GLB     _OSTCBHighRdy
    .GLB     _OSTaskSwHook

;********************************************************************************************************
;                                      CODE GENERATION DIRECTIVES
;********************************************************************************************************

    .SECTION    P, CODE
    .GLB        _OSStartHighRdy
    
;/*$PAGE*/
;*********************************************************************************************************
;                                         START MULTITASKING
;
; Description : This function is called by OSStart() to start the highest priority task that was created
;               by your application before calling OSStart().
;
; Arguments   : none
;
; Note(s)     : 1) The stack frame is assumed to look as follows:
;   
;                                                                                          LOW MEMORY
;                  OSTCBHighRdy->OSTCBStkPtr +  0  ---->  p_arg       (32-bit contents of 'p_arg')
;                                            +  4         R2
;                                            +  8         R3
;                                            + 12         R4
;                                            + 16         R5
;                                            + 20         R6
;                                            + 24         R7
;                                            + 28         R8
;                                            + 32         R9
;                                            + 36         R10
;                                            + 40         R11
;                                            + 44         R12
;                                            + 48         R12
;                                            + 52         R14
;                                            + 56         R15
;                                            + 60         task        (32-bit address of 'task')
;                                            + 64         PSW         (Initial value of 0x0000) 
;                                                                                          HIGH MEMORY
;
;               2) OSStartHighRdy() MUST:
;                      a) Call OSTaskSwHook() then,
;                      b) Switch to the highest priority task.
;*********************************************************************************************************

_OSStartHighRdy:
    MOV.L   #_OSTaskSwHook, R5           ; Execute task switch hook
    JSR     R5

    MOV.L   #_OSRunning, R5               ; Set OSRunning to TRUE
    MOV.B   #1, [R5]

    MOV.L   #_OSTCBHighRdy, R5
    MOV.L   [R5], R2
    MOV.L   [R2], SP                     ; SP = OSTCBHighRdy->OSTCBStkPtr

    OS_CTX_RESTORE

    RTE

;/*$PAGE*/
;*********************************************************************************************************
;                                       TASK LEVEL CONTEXT SWITCH
;
; Description : This function is called when a task makes a higher priority task ready-to-run.
;
; Arguments   : none
;
; Note(s)     : 1) Upon entry, 
;                  OSTCBCur     points to the OS_TCB of the task to suspend
;                  OSTCBHighRdy points to the OS_TCB of the task to resume
;
;               2) The stack frame of the task to suspend looks as follows.  This was caused by the 
;                  execution of a TRAPA #0 instruction (the registers for the task to suspend need to be 
;                  saved):
;
;                                                                                          LOW MEMORY
;                                         SP +  0  ---->  32-bit PC of task
;                                            +  4         32-bit PSW
;                                            +  8
;                                                                                          HIGH MEMORY
;
;               3) The stack frame of the task to resume looks as follows:
; 
;                                                                                          LOW MEMORY
;                  OSTCBHighRdy->OSTCBStkPtr +  0  ---->  R1
;                                            +  4         R2
;                                            +  8         R3
;                                            + 12         R4
;                                            + 16         R5
;                                            + 20         R6
;                                            + 24         R7
;                                            + 28         R8
;                                            + 32         R9
;                                            + 36         R10
;                                            + 40         R11
;                                            + 44         R12
;                                            + 48         R12
;                                            + 52         R14
;                                            + 56         R15
;                                            + 60         task        (32-bit address of 'task')
;                                            + 64         PSW         (Initial value of 0x0000) 
;                                                                                          HIGH MEMORY
;*********************************************************************************************************

                                ;added below two lines
    .RVECTOR    1, _OSCtxSw
    .GLB        _OSCtxSw

_OSCtxSw:
    OS_CTX_SAVE                                                 ; Save registers to the stack

    MOV.L   #_OSTCBCur, R5                                      ; Save current task's SP into its TCB
    MOV.L   [R5], R2
    MOV.L   SP, [R2]

    MOV.L   #_OSTaskSwHook, R5                                  ; Execute task switch hook
    JSR     R5

    MOV.L   #_OSPrioCur, R3                                     ; OSPrioCur = OSPrioHighRdy
    MOV.L   #_OSPrioHighRdy, R2
    MOV.B   [R2], [R3]

    MOV.L   #_OSTCBCur, R3                                      ; OSTCBCur = OSTCBHighRdy
    MOV.L   #_OSTCBHighRdy, R2
    MOV.L   [R2], [R3]
    MOV.L   [R3], R2
    MOV.L   [R2], SP                                            ; SP = OSTCBCur->OSTCBStkPtr

    OS_CTX_RESTORE
    RTE                                                         ; Return to task

;/*$PAGE*/
;*********************************************************************************************************
;                               PERFORM A CONTEXT SWITCH (From an ISR)
;
; Description : This function is called when an ISR makes a higher priority task ready-to-run.
;
; Arguments   : none
;
; Note(s)     : 1) Upon entry, 
;                  OSTCBCur     points to the OS_TCB of the task to suspend
;                  OSTCBHighRdy points to the OS_TCB of the task to resume
;
;               2) The stack frame of the task to suspend looks as follows.  
;
;                                                                                          LOW MEMORY
;                                                +  0         Return address of OSIntCtxSw()
;                                                +  4         R5 saved upon entry by OSIntExit
;                                                +  8         R6 saved upon entry by OSIntExit
;                                                + 12         Return address of OSIntExit() 
;                  OSTCBHighRdy->OSTCBStkPtr ->  + 16  ---->  R1
;                                                + 20         R2
;                                                + 24         R3
;                                                + 28         R4
;                                                + 32         R5
;                                                + 36         R6
;                                                + 40         R7
;                                                + 44         R8
;                                                + 48         R9
;                                                + 52         R10
;                                                + 56         R11
;                                                + 60         R12
;                                                + 64         R12
;                                                + 68         R14
;                                                + 72         R15
;                                                + 76         task        (32-bit address of 'task')
;                                                + 80         PSW         (Initial value of 0x0000) 
;                                                + 84                                      HIGH MEMORY
;
;               3) The stack frame of the task to resume looks as follows:
; 
;                                                                                          LOW MEMORY
;                  OSTCBHighRdy->OSTCBStkPtr -> +  0  ---->  R1
;                                               +  4         R2
;                                               +  8         R3
;                                               + 12         R4
;                                               + 16         R5
;                                               + 20         R6
;                                               + 24         R7
;                                               + 28         R8
;                                               + 32         R9
;                                               + 36         R10
;                                               + 40         R11
;                                               + 44         R12
;                                               + 48         R12
;                                               + 52         R14
;                                               + 56         R15
;                                               + 60         task        (32-bit address of 'task')
;                                               + 64         PSW         (Initial value of 0x0000) 
;                                                                                          HIGH MEMORY
;*********************************************************************************************************

                            ;added below two lines
    .SECTION    P, CODE
    .GLB        _OSIntCtxSw


_OSIntCtxSw:
    MOV.L   #_OSTaskSwHook, R5           ; Execute task switch hook
    JSR     R5

    MOV.L   #_OSPrioCur, R3              ; OSPrioCur = OSPrioHighRdy
    MOV.L   #_OSPrioHighRdy, R2
    MOV.B   [R2], [R3]

    MOV.L   #_OSTCBCur, R3               ; OSTCBCur = OSTCBHighRdy
    MOV.L   #_OSTCBHighRdy, R2
    MOV.L   [R2], [R3]
    MOV.L   [R3], R2
    MOV.L   [R2], SP                     ; SP = OSTCBCur->OSTCBStkPtr

    OS_CTX_RESTORE

    RTE                                  ; Return to task

    .END
